# -*- coding:utf-8 -*-

## =====================================================================
## Copyright (C) 2007-2011  Jean-Philippe GOLAY
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## =====================================================================


from Tkinter import *
import Pmw
from tkMessageBox import *

from Persistance import *
from iCalendar import CalendarGUI
from iTime import TimePopupGUI

class DiscountGUI(Toplevel):
	def __init__(self, parent=None, balloon=None, path=None, log=None):
		Toplevel.__init__(self, parent)
		self.parent=parent
		self.grab_set()
		self.transient(self.master)
		self.resizable(width=False, height=False)
		self.title(u"Remises")
		self.balloon=balloon
		self.imgSave=PhotoImage(file="img/save_icon.gif")
		self.imgDelete=PhotoImage(file="img/delete_icon.gif")
		self.imgCalendar=PhotoImage(file="img/calendar.gif")
		self.imgTime=PhotoImage(file="img/time_icon.gif")
		self.hoursListCB = Glob.HOURS_LIST
		self.minutesListCB = Glob.MINUTES_LIST
		self.path=path
		self.log=log
		# Afficher un icon personnalisé
		try:
			if os.name =="posix":
				img = PhotoImage(file=self.path+"/icons/Discount-icon.gif")
				self.tk.call("wm", "iconphoto", self._w, img)
			else:
				self.iconbitmap(default=self.path+"/icons/Discount-icon.gif")
		except TclError:
			self.log.warning("Le window manager ne supporte pas l'icône que je veux lui mettre...")
		self.log.info("\tDiscountGUI\tStart")
		self.makeDiscount()

	# DEBUT de la gestion du module Discount ------------------------------------------------------------------------------------------------------
	def clearFieldDiscount(self):
		# Mise a zéro des champs
		self.discountValues[0].set("")
		self.discountValues[1].set("")
		self.discountValues[2].set("")
		self.discountValues[3].set("")
		self.discountValues[4].set("")
		self.discountValues[5].set("")
		self.discountValues[6].set("0")
		self.discountValues[7].set("0")
		# Remise à zéro des ComboBox
		self.hourInDiscountCB.selectitem(0)
		self.minInDiscountCB.selectitem(0)
		self.hourOutDiscountCB.selectitem(0)
		self.minOutDiscountCB.selectitem(0)
		self.discountHourIn=StringVar()
		self.discountMinuteIn=StringVar()
		self.discountHourOut=StringVar()
		self.discountMinuteOut=StringVar()

	def selectDiscount(self, event):
		if self.listDiscount.get(0)!="":
			result = Discount.select(Discount.q.id==self.idListDiscount[int(self.listDiscount.curselection()[0])])
			for row in result:
				self.selectedDiscount = row
			self.discountValues[0].set(self.selectedDiscount .code)
			self.discountValues[1].set(self.selectedDiscount .description)
			self.discountValues[6].set(self.selectedDiscount .rate)
			self.discountValues[7].set(self.selectedDiscount .sum)
			# Affichage de la date de Début (self.selectedDiscount .dateIn)
			self.discountValues[2].set(self.selectedDiscount .dateIn.strftime("%d/%m/%Y"))
			# Affichage de l'heure de Début dans la ComboBox 
			count = 0
			for h in self.hoursListCB:
				if h == self.selectedDiscount .dateIn.strftime("%H"): self.hourInDiscountCB.selectitem(count)
				count+=1
			# Affichage des minutes de Début dans la ComboBox
			count = 0
			for m in self.minutesListCB:
				if m == self.selectedDiscount .dateIn.strftime("%M"): self.minInDiscountCB.selectitem(count)
				count+=1
			# Mise à jour des variables heure et minutes de Début
			self.discountHourIn.set(self.selectedDiscount .dateIn.strftime("%H"))
			self.discountMinuteIn.set(self.selectedDiscount .dateIn.strftime("%M"))
			# Affichage de la date de Fin (self.selectedDiscount .dateOut)
			self.discountValues[4].set(self.selectedDiscount .dateOut.strftime("%d/%m/%Y"))
			# Affichage de l'heure de Fin dans la ComboBox 
			count = 0
			for h in self.hoursListCB:
				if h == self.selectedDiscount .dateOut.strftime("%H"): self.hourOutDiscountCB.selectitem(count)
				count+=1
			# Affichage des minutes de Fin dans la ComboBox
			count = 0
			for m in self.minutesListCB:
				if m == self.selectedDiscount .dateOut.strftime("%M"): self.minOutDiscountCB.selectitem(count)
				count+=1
			# Mise à jour des variables heure et minutes de Fin
			self.discountHourOut.set(self.selectedDiscount .dateOut.strftime("%H"))
			self.discountMinuteOut.set(self.selectedDiscount .dateOut.strftime("%M"))
			# activation du bouton supprimer
			self.deleteDiscountBt.config(state=NORMAL)

	def searchDiscount(self, event=None):
		if self.searchDiscountValue.get() != "":
			self.listDiscount.delete(0,END)
			self.idListDiscount = []
			result = Discount.select(Discount.q.description.startswith(self.searchDiscountValue.get().encode("utf-8")), orderBy=Discount.q.dateIn)
			for row in result:
				self.listDiscount.insert(END, row.dateIn.strftime("%d/%m/%Y %H:%M")+" au "+row.dateOut.strftime("%d/%m/%Y %H:%M")+" - "+row.description)
				self.idListDiscount.append(row.id)
		else:
			self.listDiscount.delete(0,END)
			self.idListDiscount = []
			result = Discount.select(orderBy=Discount.q.dateIn)
			for row in result:
				self.listDiscount.insert(END, row.dateIn.strftime("%d/%m/%Y %H:%M")+" au "+row.dateOut.strftime("%d/%m/%Y %H:%M")+" - "+row.description)
				self.idListDiscount.append(row.id)

	def makeDiscount(self):
		leftFrame = Frame(self)
		# Fiche Discount  (présentation colonne de gauche)
		Label(leftFrame, text=u"Remise").pack(side=TOP, fill=X)
		# Création des champs a renseigner pour un object Discount
		discountLabels = (u"Code", u"Déscription", u"Début (date)", u"Début (heure)", u"Fin (date)", u"Fin (heure)", u"Taux", u"Montant")
		self.discountValues = [StringVar(), StringVar(), StringVar(), StringVar(), StringVar(), StringVar(), StringVar(), StringVar()]
		count = 0
		for name in discountLabels:
			f = Frame(leftFrame)
			Label(f, width=12, text=name, anchor=W).pack(side=LEFT)
			if count == 2:  # Date debut
				Entry(f, textvariable=self.discountValues[count], width=21).pack(side=LEFT, fill=X)
				myCal1=Button(f, image=self.imgCalendar, command=lambda x=self.discountValues[count]:self.ctrlCalendar(x), padx=4, pady=1)
				myCal1.pack(side=LEFT)
				self.balloon.bind(myCal1, u"Calendrier")
			elif count == 3:  # Heure debut
				hStartLb1=Label(f, width=2, text="H", anchor=W)
				hStartLb1.pack(side=LEFT)
				self.balloon.bind(hStartLb1, u"Heure")
				self.hourInDiscountCB=Pmw.ComboBox(f, selectioncommand=self.discountHourIn, scrolledlist_items=self.hoursListCB, listheight=100)
				self.hourInDiscountCB._entryfield._entryFieldEntry.config( width = 3)
				self.hourInDiscountCB.pack(side=LEFT)
				mStartLb1=Label(f, width=3, text="mn", anchor=W)
				mStartLb1.pack(side=LEFT)
				self.balloon.bind(mStartLb1, u"minutes")
				self.minInDiscountCB=Pmw.ComboBox(f, selectioncommand=self.discountMinuteIn, scrolledlist_items=self.minutesListCB, listheight=100)
				self.minInDiscountCB._entryfield._entryFieldEntry.config( width = 3)
				self.minInDiscountCB.pack(side=LEFT)
				# Menu Time
				myTime1=Button(f, image=self.imgTime, padx=1, pady=1)
				myTime1.pack(side=RIGHT)
				myTime1.bind("<ButtonRelease-1>",self.ctrlTimeNow1)
				self.balloon.bind(myTime1, u"Séléctionner une heure")
			elif count == 4:  # Date Fin
				Entry(f, textvariable=self.discountValues[count], width=21).pack(side=LEFT, fill=X)
				myCal2=Button(f, image=self.imgCalendar, command=lambda x=self.discountValues[count]:self.ctrlCalendar(x), padx=4, pady=1)
				myCal2.pack(side=LEFT)
				self.balloon.bind(myCal2, u"Calendrier")
			elif count == 5: # Heure Fin
				hStartLb2=Label(f, width=2, text="H", anchor=W)
				hStartLb2.pack(side=LEFT)
				self.balloon.bind(hStartLb2, u"Heure")
				self.hourOutDiscountCB=Pmw.ComboBox(f, selectioncommand=self.discountHourOut, scrolledlist_items=self.hoursListCB, listheight=100)
				self.hourOutDiscountCB._entryfield._entryFieldEntry.config( width = 3)
				self.hourOutDiscountCB.pack(side=LEFT)
				mStartLb2=Label(f, width=3, text="mn", anchor=W)
				mStartLb2.pack(side=LEFT)
				self.balloon.bind(mStartLb2, u"minutes")
				self.minOutDiscountCB=Pmw.ComboBox(f, selectioncommand=self.discountMinuteOut, scrolledlist_items=self.minutesListCB, listheight=100)
				self.minOutDiscountCB._entryfield._entryFieldEntry.config( width = 3)
				self.minOutDiscountCB.pack(side=LEFT)
				# Menu Time
				myTime2=Button(f, image=self.imgTime, padx=1, pady=1)
				myTime2.pack(side=RIGHT)
				myTime2.bind("<ButtonRelease-1>",self.ctrlTimeNow2)
				self.balloon.bind(myTime2, u"Séléctionner une heure")
			else: 
				Entry(f, textvariable=self.discountValues[count], width=24).pack(side=LEFT, fill=X)
			f.pack(side=TOP, fill=X)
			count += 1
		# Boutons enregistrement (new ou modify) et suppression
		s = Frame(leftFrame) 
		self.saveDiscountBt=Button(s, image=self.imgSave, command=self.createDiscount)
		self.saveDiscountBt.bind("<Return>", self.createDiscount)
		self.saveDiscountBt.pack(side=LEFT)
		self.balloon.bind(self.saveDiscountBt, u"Enregistrer")
		self.deleteDiscountBt=Button(s, image=self.imgDelete, command=self.deleteDiscount, state=DISABLED)
		self.deleteDiscountBt.bind("<Return>", self.deleteDiscount)
		self.deleteDiscountBt.pack(side=LEFT)
		self.balloon.bind(self.deleteDiscountBt, u"Supprimer")
		s.pack(side=TOP, fill=X)
		leftFrame.pack(side=LEFT, fill=X)
		# Liste des Discount existants (présentation colonne de droite)
		rightFrame = Frame(self) 
		Label(rightFrame, text=u"Liste des Remises").pack(side=TOP, fill=X)
		self.searchDiscountValue = StringVar()
		self.searchDiscountEt = Entry(rightFrame,  width=63, textvariable=self.searchDiscountValue, relief=GROOVE)
		self.searchDiscountEt.bind("<KeyRelease>", self.searchDiscount)
		self.searchDiscountEt.pack(side=TOP, fill=X)
		self.balloon.bind(self.searchDiscountEt, u"Saisir les premières lettres d'une remise (discount)\npour une recherche plus précise,\nla liste est classée par date de début.")
		s = Frame(rightFrame) 
		scrollbar = Scrollbar(s)
		scrollbar.pack(side=RIGHT, fill=Y)
		self.listDiscount = Listbox(s)
		self.listDiscount.config(yscrollcommand=scrollbar.set, width=60, selectmode=SINGLE, height=11)
		self.listDiscount.bind("<ButtonRelease-1>",self.selectDiscount)
		scrollbar.config(command=self.listDiscount.yview)
		self.listDiscount.pack()
		self.balloon.bind(self.listDiscount, u"Séléctionner une remise (discount)\npour la visualiser ou la modifier.")
		s.pack(side=TOP, fill=X)
		rightFrame.pack(side=RIGHT, fill=BOTH)
		# Initialisation
		self.clearFieldDiscount()
		self.searchDiscount()

	def ctrlTimeNow1(self,event):
		varHour=[self.discountHourIn, self.discountMinuteIn, self.hourInDiscountCB, self.minInDiscountCB] 
		TimePopupGUI(self, event=event, field=self.discountValues[3], varHour=varHour, log=self.log, path=self.path)

	def ctrlTimeNow2(self,event):
		varHour=[self.discountHourOut, self.discountMinuteOut, self.hourOutDiscountCB, self.minOutDiscountCB]
		TimePopupGUI(self, event=event, field=self.discountValues[5], varHour=varHour, log=self.log, path=self.path)

	def ctrlCalendar(self,field):
		CalendarGUI(field=field, log=self.log, path=self.path)

	def discountHourIn(self, value):
		self.discountHourIn.set(value)
		self.minInDiscountCB.selectitem(0)
		self.minInDiscountCB.invoke()

	def discountMinuteIn(self, value):
		self.discountMinuteIn.set(value)

	def discountHourOut(self, value):
		self.discountHourOut.set(value)
		self.minOutDiscountCB.selectitem(0)
		self.minOutDiscountCB.invoke()

	def discountMinuteOut(self, value):
		self.discountMinuteOut.set(value)

	def getDateTimeInDiscount(self):
		# Récuperer l"année
		date=self.discountValues[2].get().split("/")
		d = datetime.datetime(int(date[2]), int(date[1]), int(date[0]), int(self.discountHourIn.get()), int(self.discountMinuteIn.get()), 0)
		return d

	def getDateTimeOutDiscount(self):
		# Récuperer l"année
		date=self.discountValues[4].get().split("/")
		d = datetime.datetime(int(date[2]), int(date[1]), int(date[0]), int(self.discountHourOut.get()), int(self.discountMinuteOu.get()), 0)
		return d

	def verifyDiscount(self):
		if self.discountValues[0].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Code est obligatoire !\nMerci de le compléter.")
			return False
		elif self.discountValues[1].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Déscription est obligatoire !\nMerci de le compléter.")
			return False
		elif self.discountValues[2].get() == "": # TODO Créer une fonction validDate()
			showerror(u"Erreur de saisie", u"Le champ Date début est obligatoire !\nMerci de le compléter.")
			return False
		elif self.discountHourIn.get() == "" or  self.discountMinuteIn.get() == "": # TODO Créer une fonction validTime()
			showerror(u"Erreur de saisie", u"Les champs Heures et Minutes début sont obligatoire !\nMerci de le compléter.")
			return False
		elif self.discountValues[4].get() == "": # TODO Créer une fonction validDate()
			showerror(u"Erreur de saisie", u"Le champ Date fin est obligatoire !\nMerci de le compléter.")
			return False
		elif self.discountHourOut.get() == "" or  self.discountMinuteOut.get() == "": # TODO Créer une fonction validTime()
			showerror(u"Erreur de saisie", u"Les champs Heures et Minutes fin sont obligatoire !\nMerci de le compléter.")
			return False
		elif self.discountValues[6].get() == "": # TODO Créer une fonction nombres
			showerror(u"Erreur de saisie", u"Le champ Taux est obligatoire !\nMerci de le compléter.")
			return False
		elif self.discountValues[7].get() == "": # TODO Créer une fonction nombres
			showerror(u"Erreur de saisie", u"Le champ Montant est obligatoire !\nMerci de le compléter.")
			return False
		else:
			return True

	def createDiscount(self, event=None):
		if self.verifyDiscount():
			if  self.deleteDiscountBt.config()["state"][4] == "normal":
				self.modifyDiscount()
			else:
				if askyesno(u"Enregistrement", u"Souhaitez-vous enregistrer %s comme une nouvelle remise (discoune) ?\n" % self.discountValues[1].get()):
					Discount(code=self.discountValues[0].get().encode("utf-8"),
						description=self.discountValues[1].get().encode("utf-8"),
						dateIn=self.getDateTimeInDiscount(),
						dateOut=self.getDateTimeOutDiscount(),
						rate=self.discountValues[6].get().encode("utf-8"),
						sum=self.discountValues[7].get().encode("utf-8"),
						createDate=datetime.datetime.now()
					)
					self.searchDiscount()
				self.clearFieldDiscount()

	def modifyDiscount(self, event=None): 
		if askyesno(u"Modifier", u"Souhaitez-vous modifier la remise (discount) %s ?" % self.selectedDiscount.description):
			self.selectedDiscount.code=self.discountValues[0].get().encode("utf-8")
			self.selectedDiscount.description=self.discountValues[1].get().encode("utf-8")
			self.selectedDiscount.dateIn=self.getDateTimeInDiscount()
			self.selectedDiscount.dateOut=self.getDateTimeOutDiscount()
			self.selectedDiscount.rate=self.discountValues[6].get().encode("utf-8")
			self.selectedDiscount.sum=self.discountValues[7].get().encode("utf-8")
			self.searchDiscount()
		self.deleteDiscountBt.config(state=DISABLED)
		self.clearFieldDiscount()

	def deleteDiscount(self, event=None):
		if askyesno(u"Suppression", u"Souhaitez-vous supprimer la remise (discount) %s ?\nCette opération est irréversible !" % self.selectedDiscount.description):
			Discount.delete(self.selectedDiscount.id)
			self.searchDiscount()
		self.deleteDiscountBt.config(state=DISABLED)
		self.clearFieldDiscount()
	# FIN de la gestion du module Discount ----------------------------------------------------------------------------------------------------------

class DiscountListGUI(Toplevel):
	def __init__(self, parent=None, balloon=None, field=None, index=None, listObject=None, path=None, log=None):
		Toplevel.__init__(self, parent)
		self.parent=parent
		self.grab_set()
		self.transient(self.master)
		self.resizable(width=False, height=False)
		self.title(u"Liste des Remises")
		self.balloon=balloon
		self.imgNew=PhotoImage(file="img/add_alternative_icon.gif")
		self.field=field
		self.index=index
		self.listObject=listObject
		self.path=path
		self.log=log
		# Afficher un icon personnalisé
		try:
			if os.name =="posix":
				img = PhotoImage(file=self.path+"/icons/Discount-icon.gif")
				self.tk.call("wm", "iconphoto", self._w, img)
			else:
				self.iconbitmap(default=self.path+"/icons/Discount-icon.gif")
		except TclError:
			self.log.warning("Le window manager ne supporte pas l'icône que je veux lui mettre...")
		self.log.info("\tDiscountListGUI\tStart")
		self.makeListDiscount()

	def selectListDiscount(self, event):
		if self.listListDiscount.get(0)!="":
			result = Discount.select(Discount.q.id==self.idListListDiscount[int(self.listListDiscount.curselection()[0])])
			for row in result:
				self.listObject[self.index]=row
				self.field.set(row.code+" - "+row.description)
				self.destroy()

	def searchListDiscount(self, event=None):
		if self.searchListDiscountValue.get() != "":
			self.listListDiscount.delete(0,END)
			self.idListListDiscount = []
			result = Discount.select(Discount.q.description.startswith(self.searchListDiscountValue.get().encode("utf-8")), orderBy=Discount.q.description)
			for row in result:
				self.listListDiscount.insert(END, row.code+" - "+row.description)
				self.idListListDiscount.append(row.id)
		else:
			self.listListDiscount.delete(0,END)
			self.idListListDiscount = []
			result = Discount.select(orderBy=Discount.q.description)
			for row in result:
				self.listListDiscount.insert(END, row.code+" - "+row.description)
				self.idListListDiscount.append(row.id)

	def makeListDiscount(self):
		leftFrame = Frame(self)
		Label(leftFrame, text=u"Liste des Discounts").pack(side=TOP, fill=X)
		self.searchListDiscountValue = StringVar()
		s = Frame(leftFrame)
		self.searchListDiscountEt = Entry(s,  width=42, textvariable=self.searchListDiscountValue, relief=GROOVE)
		self.searchListDiscountEt.bind("<KeyRelease>", self.searchListDiscount)
		self.searchListDiscountEt.pack(side=LEFT, fill=X)
		self.balloon.bind(self.searchListDiscountEt, u"Saisir les premiéres lettres d'un Discount\npour une recherche plus précise,\nla liste est classée par description.")
		newDiscountBt=Button(s, image=self.imgNew, command=self.ctrlDiscount)
		newDiscountBt.pack(side=RIGHT)
		self.balloon.bind(newDiscountBt, u"Créer une nouvelle Remise")
		s.pack(side=TOP, fill=X)
		s = Frame(leftFrame)
		scrollbar = Scrollbar(s)
		scrollbar.pack(side=RIGHT, fill=Y)
		self.listListDiscount = Listbox(s)
		self.listListDiscount.config(yscrollcommand=scrollbar.set,width=43, selectmode=SINGLE, height=16)
		self.listListDiscount.bind("<ButtonRelease-1>",self.selectListDiscount)
		scrollbar.config(command=self.listListDiscount.yview)
		self.listListDiscount.pack()
		self.balloon.bind(self.listListDiscount, u"Séléctionner un Discount.")
		s.pack(side=TOP, fill=X)
		leftFrame.pack()
		self.searchListDiscount()

	def ctrlDiscount(self):
		DiscountGUI(balloon=self.balloon, log=self.log, path=self.path)